﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Navigation;
using System.Windows.Media.Imaging;
using System.Windows.Threading;

namespace ChessOnline
{
    public partial class GamePage : Page
    {
        GameDrawer gDrawer = new GameDrawer();
        GameLogic gLogic = new GameLogic();
        GamesManager gManager = new GamesManager();
        DispatcherTimer timer = new DispatcherTimer();

        public GamePage()
        {
            InitializeComponent();
        }

        // Executes when the user navigates to this page.
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
        }

        void GamePage_Loaded(object sender, RoutedEventArgs e)
        {
            // Восстанавливаем менеджер игр
            gManager = App.Session.ContainsKey("gamesManager") ? 
                App.Session["gamesManager"] as GamesManager : new GamesManager();

            gLogic.SetGameInfo(gManager.GetGameInfo());

            // Отрисовываем доску
            gDrawer.Canvas = chessCanvas;
            gDrawer.ChessBoardDrawBackground();
            chessCanvas = gDrawer.Canvas;

            // Инициализируем события
            Authorization.Instance.ThrowAuthorizationCompleted += new Authorization.EventHandler(AuthorizationCompleted);
            gLogic.ThrowUpdatePositionsEnded += new GameLogic.EventHandler(UpdatePositionsEnded);
            gLogic.ThrowGetEnemyNameCompleted += new GameLogic.EventHandler(GetEnemyNameCompleted);
            gLogic.ThrowUpdateGameInfoCompleted += new GameLogic.EventHandler(UpdateGameInfoCompleted);
            gLogic.ThrowPickChessCompleted += new GameLogic.EventHandler(PickChessCompleted);
            gLogic.ThrowMoveChessCompleted += new GameLogic.EventHandler(MoveChessCompleted);

            // Инициализировать таймер
            timer.Interval = new TimeSpan(0, 0, 2);
            timer.Tick += new EventHandler(TimerTickEntryPoint);
            timer.Start();

            // Расставим фигуры изначально
            gLogic.RequestUpdatePositions();
        }

        void TimerTickEntryPoint(object sender, EventArgs e)
        {
            Authorization.Instance.CheckAuthorization();
        }

        void AuthorizationCompleted(object sender, object args)
        {
            if (!Authorization.Instance.IsAuthorized())
            {// Если не авторизован, то перенаправляем на страницу авторизации
                NavigationService.Navigate(new Uri("/HomePage", UriKind.Relative));
            }
            else
            {// Если авторизован
                // Обновим доску и фигуры
                gLogic.RequestUpdateGameInfo();
            }
        }

        void UpdateGameInfoCompleted(object sender, object args)
        {
            if (gLogic.GetWinnerName() != "")
            {// Завершить игру TODO: дописать эту часть в будущем
                informationTextBlock.Text = "Игра завершена. Победитель: " + gLogic.GetWinnerName();
                leaveGameButton.Content = "Перейти в меню игр";
            }
            else
            {// Продолжить игру
                // Обновить позиции шахмат на доске
                gLogic.RequestUpdatePositions();
            }
        }

        void UpdatePositionsEnded(object sender, object args)
        {
            if (informationTextBlock.Text == "Ожидание подключения игрока")
            {
                gLogic.RequestEnemyName();
            }

            gDrawer.Canvas = chessCanvas;
            gDrawer.UpdatePositions(gLogic.GetCells());
            chessCanvas = gDrawer.Canvas;
        }

        void GetEnemyNameCompleted(object sender, object args)
        {
            if (gLogic.GetEnemyName() != "")
            {
                informationTextBlock.Text = "Ваш противник: " + gLogic.GetEnemyName();
            }
        }

        void chessCanvas_Clicked(object sender, MouseButtonEventArgs e)
        {
            if (gLogic.IsStarted())
            {
                if (gDrawer.HasHighlightedCells())
                {
                    gLogic.RequestMoveChess(e.GetPosition(chessCanvas));
                }
                else
                {
                    gLogic.RequestPickChess(e.GetPosition(chessCanvas));
                }
            }
        }

        void MoveChessCompleted(object sender, object args)
        {
            gDrawer.Canvas = chessCanvas;
            gDrawer.ClearHighlights();
            chessCanvas = gDrawer.Canvas;
        }

        void PickChessCompleted(object sender, object args)
        {
            gDrawer.Canvas = chessCanvas;            
            gDrawer.SetHighlights(gLogic.GetMarkedPasses());
            chessCanvas = gDrawer.Canvas;
        }

        private void LeaveGameButton_Clicked(object sender, RoutedEventArgs e)
        {
            NavigationService.Navigate(new Uri("/GamesPage", UriKind.Relative));
            gLogic.RequestQuitGame();
        }

        void GamePage_Unloaded(object sender, RoutedEventArgs e)
        {
            timer.Stop();
            timer.Tick -= new EventHandler(TimerTickEntryPoint);

            Authorization.Instance.ThrowAuthorizationCompleted -= new Authorization.EventHandler(AuthorizationCompleted);
            gLogic.ThrowUpdatePositionsEnded -= new GameLogic.EventHandler(UpdatePositionsEnded);
            gLogic.ThrowGetEnemyNameCompleted -= new GameLogic.EventHandler(GetEnemyNameCompleted);
            gLogic.ThrowUpdateGameInfoCompleted -= new GameLogic.EventHandler(UpdateGameInfoCompleted);
            gLogic.ThrowPickChessCompleted -= new GameLogic.EventHandler(PickChessCompleted);
            gLogic.ThrowMoveChessCompleted -= new GameLogic.EventHandler(MoveChessCompleted);

            // При закрытии страницы послать сигнал выхода из игры
            gLogic.RequestQuitGame();
        }
    }
}
